package com.phiture.erp.produce.core.service.impl;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.phiture.erp.produce.common.enums.ErpProduceInBackFlushStatusEnum;
import com.phiture.erp.produce.core.pojo.vo.ProduceInEventPageReqVO;
import com.phiture.erp.produce.core.pojo.vo.ProduceInEventSaveReqVO;
import com.phiture.erp.produce.core.service.ErpProduceInEventService;
import com.phiture.erp.produce.dal.entity.ErpProduceInEventDO;
import com.phiture.erp.produce.dal.entity.ErpProduceInEventItemsDO;
import com.phiture.erp.produce.dal.mapper.ProduceInEventItemsMapper;
import com.phiture.erp.produce.dal.mapper.ProduceInEventMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;


import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.phiture.erp.common.constants.ErrorCodeConstants.PRODUCE_IN_EVENT_NOT_EXISTS;

/**
 * 生产入库事务 Service 实现类
 *
 * @author lekaihuai
 */
@Service
@Validated
public class ErpProduceInEventServiceImpl implements ErpProduceInEventService {

    @Resource
    private ProduceInEventMapper produceInEventMapper;
    @Resource
    private ProduceInEventItemsMapper produceInEventItemsMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createProduceInEvent(ProduceInEventSaveReqVO createReqVO) {
        // 插入
        ErpProduceInEventDO produceInEvent = BeanUtils.toBean(createReqVO, ErpProduceInEventDO.class);
        produceInEventMapper.insert(produceInEvent);

        // 插入子表
        if(createReqVO.getProduceInEventItemss() != null && !createReqVO.getProduceInEventItemss().isEmpty()) {
            createProduceInEventItemsList(produceInEvent.getId(), createReqVO.getProduceInEventItemss());
        }

        // 返回
        return produceInEvent.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProduceInEvent(ProduceInEventSaveReqVO updateReqVO) {
        // 校验存在
        validateProduceInEventExists(updateReqVO.getId());
        // 更新
        ErpProduceInEventDO updateObj = BeanUtils.toBean(updateReqVO, ErpProduceInEventDO.class);
        produceInEventMapper.updateById(updateObj);

        // 更新子表
        if(updateReqVO.getProduceInEventItemss() != null && !updateReqVO.getProduceInEventItemss().isEmpty()) {
            updateProduceInEventItemsList(updateReqVO.getId(), updateReqVO.getProduceInEventItemss());
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProduceInEvent(Long id) {
        // 校验存在
        validateProduceInEventExists(id);
        // 删除
        produceInEventMapper.deleteById(id);

        // 删除子表
        deleteProduceInEventItemsByParentId(id);
    }

    private void validateProduceInEventExists(Long id) {
        if (produceInEventMapper.selectById(id) == null) {
            throw exception(PRODUCE_IN_EVENT_NOT_EXISTS);
        }
    }

    @Override
    public ErpProduceInEventDO getProduceInEvent(Long id) {
        return produceInEventMapper.selectById(id);
    }

    @Override
    public PageResult<ErpProduceInEventDO> getProduceInEventPage(ProduceInEventPageReqVO pageReqVO) {
            return produceInEventMapper.selectPage(pageReqVO, new LambdaQueryWrapperX<ErpProduceInEventDO>()
                    .eqIfPresent(ErpProduceInEventDO::getProduceInId, pageReqVO.getProduceInId())
                    .eqIfPresent(ErpProduceInEventDO::getInType, pageReqVO.getInType())
                    .betweenIfPresent(ErpProduceInEventDO::getCreateTime, pageReqVO.getCreateTime())
                    .eqIfPresent(ErpProduceInEventDO::getStatus, pageReqVO.getStatus())
                    .eqIfPresent(ErpProduceInEventDO::getProduceInNo, pageReqVO.getProduceInNo())
                    .eqIfPresent(ErpProduceInEventDO::getProcessResult, pageReqVO.getProcessResult())
                    .orderByDesc(ErpProduceInEventDO::getId));
    }

    @Override
    public List<ErpProduceInEventDO> getProduceInEventList() {
        return produceInEventMapper.selectList(new LambdaQueryWrapperX<ErpProduceInEventDO>()
                        .in(ErpProduceInEventDO::getStatus, ErpProduceInBackFlushStatusEnum.WAIT_DOING.getStatus(),ErpProduceInBackFlushStatusEnum.ERROR.getStatus())
                        .orderByDesc(ErpProduceInEventDO::getId));
    }

    // ==================== 子表（生产入库事务明细） ====================

    @Override
    public List<ErpProduceInEventItemsDO> getProduceInEventItemsListByParentId(Long parentId) {
        return produceInEventItemsMapper.selectListByParentId(parentId);
    }

    private void createProduceInEventItemsList(Long parentId, List<ErpProduceInEventItemsDO> list) {
        list.forEach(o -> o.setParentId(parentId));
        produceInEventItemsMapper.insertBatch(list);
    }

    private void updateProduceInEventItemsList(Long parentId, List<ErpProduceInEventItemsDO> list) {
        deleteProduceInEventItemsByParentId(parentId);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createProduceInEventItemsList(parentId, list);
    }

    private void deleteProduceInEventItemsByParentId(Long parentId) {
        produceInEventItemsMapper.deleteByParentId(parentId);
    }

}